/*=====================
 * 名称: rShow
 * 功能: 滑动展示
 * 版本: 0.1.5
 * 作者: zjsina
 * 时间: 2014-05-13
 ======================*/
(function(w) {
	var container, //容器
	myCanvas, //canvas
	myCanvasTx, //canvas context
	r_version = "0.1.5", //version
	spW, //展示区宽度
	spH, //展示区长度
	cX, //圆心x坐标
	cY, //圆心y坐标
	pages = [], //存储页面信息数组
	actPieces = [], //存储动画前信息
	pieces = [], //存储模块信息
	actTimer = [], //动画定时管理器
	rad = Math.PI / 180, //转换弧度制
	flg = false, //标记是否滑动
	dirinit = true, //标记方向初始化
	canchange = true, //标记自动切换是否结束
	rinitFlg = true, //标记rShow是否是初次加载
	angle, //标记转动角度
	startY, //标记起始位置
	move, //滑动距离
	prepage, //标记上一页
	nowpage = 0, //标记当前页
	nextpage, //标记下一页
	actTimer, //动画计时器
	getpiece = /@(\d+)/g, // getpiece RegExp
	context, //获取选择器
	pieceSelector, //选择器
	rShow = function(selector) {
		context = selector;
		return new rShow.fn.init(selector);
	}
	rShow.fn = rShow.prototype = {
		// The current version of rShow being used
		rShow : r_version,
		//constructor
		constructor : rShow,
		//初始化 参数：选择器
		init : function(selector) {
			pieceSelector = [];
			if (getpiece.test(selector)) {
				//获取选择器信息
				pieceSelector = selector.match(getpiece);
				var pcsNum = pieceSelector.length;
				for (var i = 0; i < pcsNum; i++) {
					pieceSelector[i] = pieceSelector[i].replace(/[^0-9]/, "");
				}
			} else {
				//创建canvas
				if (!myCanvas) {
					container = document.getElementById(selector);
					spW = container.clientWidth;
					spH = container.clientHeight;
					cX = spW;
					cY = 0.5 * spH;
					container.innerHTML = '<canvas id="myCanvas" width="' + spW + '" height="' + spH + '"></canvas>'
					myCanvas = document.getElementById("myCanvas");
					myCanvasTx = myCanvas.getContext("2d");
				}
			}
			return this;
		},
		//添加滑动页 参数：页面信息
		addpage : function(detail) {
			pages.push(detail);
			return this;
		},
		//准备完成 参数：回调函数
		ready : function(callback) {
			var count = 0, //加载计数
			total = 0, //总数计数
			piecesImg, //储存图片
			piecesR, //标记半径
			piecesA, //标记角度
			psNum = pages.length
			for (var i = 0; i < psNum; i++) {
				total += pages[i].modules;
				for (var j = 0; j < pages[i].modules; j++) {
					piecesImg = new Image();
					piecesImg.src = Array.isArray(pages[i].img) ? pages[i].img[j] : pages[i].img;
					piecesImg.onload = function() {
						if (++count == total)
							callback();
					}
					piecesR = Array.isArray(pages[i].radius) ? pages[i].radius[j] : pages[i].radius;
					piecesA = Array.isArray(pages[i].angle) ? pages[i].angle[j] : pages[i].angle;
					pieces.push({
						p : i,
						m : j,
						r : piecesR,
						a : piecesA,
						image : piecesImg,
						x : cX - piecesR * Math.sin(piecesA * rad),
						y : cY - piecesR * Math.cos(piecesA * rad),
						width : Array.isArray(pages[i].width) ? pages[i].width[j] : pages[i].width,
						height : Array.isArray(pages[i].height) ? pages[i].height[j] : pages[i].height
					});
				}
			}
		},
		//事件监听  参数：容器，类型，函数
		addEvent : function(el, type, fn) {
			if (el.addEventListener)
				el.addEventListener(type, fn, false);
			else
				el['on' + type] = fn;
		},
		//取消浏览器默认行为  参数：event
		stop : function(e) {
			//Opera/Chrome/FF
			if (e.preventDefault)
				e.preventDefault();
			//IE
			e.returnValue = false;
		},
		//模块出现
		show : function() {
			var pcsNum = pieceSelector.length;
			for (var i = 0; i < pcsNum; i++) {
				var target = pieces[pieceSelector[i]];
				myCanvasTx.drawImage(target.image, target.x, target.y, target.width, target.height);
			}
		},
		//模块消失
		hid : function() {
			var pcsNum = pieceSelector.length;
			for (var i = 0; i < pcsNum; i++) {
				var target = pieces[pieceSelector[i]];
				myCanvasTx.clearRect(target.x, target.y, target.width, target.height);
			}
		},
		//简单动画 参数：动画类型，具体数值，回调
		act : function(type, attr, t, fn) {
			var pcsNum = pieceSelector.length;
			for (var i = 0; i < pcsNum; i++) {
				var target = pieces[pieceSelector[i]], //替换目标
				aMove = 0//act 移动距离
				actPieces[i] = {
					x : target.x,
					y : target.y,
					a : target.a,
					r : target.r,
					num : pieceSelector[i]
				};
				var actTimerNum = actTimer.length;
				actTimer.push(setInterval(function() {
					myCanvasTx.clearRect(target.x, target.y, target.width, target.height);
					attr > 0 ? aMove += 4 : aMove -= 4;
					switch(type) {
						case 'left':
							attr > 0 ? target.x += 4 : target.x -= 4;
							target.r = (cX - target.x) / Math.sin(target.a * rad);
							break;
						case 'top':
							attr > 0 ? target.y += 4 : target.y -= 4;
							target.a = Math.acos((cY - target.y) / target.r) / rad;
							break;
						default:
							rShow.rError("No such act!");
					}
					if (attr > 0 && aMove >= attr || attr < 0 && aMove <= attr)
						clearInterval(actTimer[actTimerNum]);
					myCanvasTx.drawImage(target.image, target.x, target.y, target.width, target.height);
				}, t));
			}
		},
		//动画结束重置
		actReset : function() {
			var apNum = actPieces.length, actTimerNum = actTimer.length;
			for (var i = 0; i < apNum; i++) {
				pieces[actPieces[i].num].x = actPieces[i].x;
				pieces[actPieces[i].num].y = actPieces[i].y;
				pieces[actPieces[i].num].a = actPieces[i].a;
				pieces[actPieces[i].num].r = actPieces[i].r;
				if (i == apNum - 1)
					actPieces = [];
			}
			for (var i = 0; i < actTimerNum; i++) {
				clearInterval(actTimer[i]);
				if (i == actTimerNum - 1)
					actTimer = [];
			}

		},
		//点击事件
		rclick : function(callback, remove) {
			if (!remove) {
				container['onclick'] = fn;
			} else {
				container['onclick'] = null;
			}
			function fn(e) {
				var p = {
					x : e.offsetX || e.layerX,
					y : e.offsetY || e.layerY
				}
				r.rdraw(p, pieceSelector, callback);
			}

		},
		//动作函数
		move : function(moveEndCallback) {
			if (rinitFlg) {
				moveEndCallback(0);
				rinitFlg = false;
			}
			//移动初始化
			r.drawImg(nowpage, 0, 0);
			//鼠标事件注册
			this.addEvent(container, 'mousedown', moveStart);
			this.addEvent(container, 'mousemove', moveIn);
			this.addEvent(container, 'mouseup', moveEnd);
			//移动设备触摸事件注册
			this.addEvent(container, 'touchstart', moveStart);
			this.addEvent(container, 'touchmove', moveIn);
			this.addEvent(container, 'touchend', moveEnd);

			//canvas转动 参数：角度，方向，滑动是否结束
			function canvasMove(m, end) {
				clearInterval(actTimer);
				if (m) {
					if (dirinit) {
						m > 0 ? dir = 1 : dir = -1;
						dirinit = false;
					}
					myCanvasTx.clearRect(0, 0, spW, spH);
					nowpage == pages.length - 1 ? nextpage = 0 : nextpage = nowpage + 1;
					nowpage == 0 ? prepage = pages.length - 1 : prepage = nowpage - 1;
					if (!end) {
						if (dir > 0)
							angle = -move * r.getPageAngle(pages[nextpage].angle) / spH;
						else
							angle = -move * r.getPageAngle(pages[prepage].angle) / spH;
						r.drawImg(nextpage, angle, 1);
						r.drawImg(nowpage, angle, 0);
						r.drawImg(prepage, angle, -1);
					} else {
						r(context).rclick(0, 1);
						if (m > 0) {
							nowpage == pages.length - 1 ? nowpage = 0 : nowpage++;
						} else {
							nowpage == 0 ? nowpage = pages.length - 1 : nowpage--;
						}
						nowpage == pages.length - 1 ? nextpage = 0 : nextpage = nowpage + 1;
						nowpage == 0 ? prepage = pages.length - 1 : prepage = nowpage - 1;
						autoTurn(angle, m);
					}
				} else {
					canchange = true;
				}
			}

			function autoTurn(a, d) {
				var ang// 标记已转角度
				d > 0 ? ang = Math.floor(90 + a) : ang = Math.floor(a - 90);
				var timer = setInterval(function() {
					if (ang == 0) {
						clearInterval(timer);
						canchange = true;
						r(context).actReset();
						moveEndCallback(nowpage, myCanvasTx);
					} else {
						myCanvasTx.clearRect(0, 0, spW, spH);
						myCanvasTx.save();
						myCanvasTx.translate(cX, cY);
						myCanvasTx.rotate(ang * rad);
						myCanvasTx.translate(-cX, -cY);
						r.drawImg(nextpage, 0, 1);
						r.drawImg(nowpage, 0, 0);
						r.drawImg(prepage, 0, -1);
						d > 0 ? ang-- : ang++;
						myCanvasTx.restore();
					}
				}, pages[nowpage].speed)
			}

			//滑动开始 参数：event
			function moveStart(e) {
				if (canchange) {
					flg = true;
					dirinit = true;
					if (e.touches)
						e = e.touches[0];
					move = 0;
					startY = e.clientY;
				}
			}

			//滑动中 参数：event
			function moveIn(e) {
				if (flg && canchange) {
					r.fn.stop(e);
					if (e.touches)
						e = e.touches[0];
					move = e.clientY - startY;
					canvasMove(move, false);
				}
			}

			//滑动结束 参数：event
			function moveEnd(e) {
				if (canchange) {
					r.fn.stop(e);
					flg = false;
					canchange = false;
					canvasMove(move, true);
				}
			}

		}
	}
	rShow.fn.init.prototype = rShow.fn;
	//重绘判定事件是否在模块区域内
	rShow.rdraw = function(p, selector, fn) {
		var sNum = selector.length;
		for (var i = 0; i < sNum; i++) {
			var piece = pieces[pieceSelector[i]];
			myCanvasTx.beginPath();
			myCanvasTx.globalAlpha = 0;
			myCanvasTx.rect(piece.x, piece.y, piece.width, piece.height);
			myCanvasTx.stroke();
			myCanvasTx.globalAlpha = 1;
			if (p && myCanvasTx.isPointInPath(p.x, p.y) && fn) {
				fn();
			}
		}
	}
	//rShow错误返回 参数：错误
	rShow.rError = function(msg) {
		throw new Error('rShow: ' + msg);
	}
	//获取页面旋转角 参数：角度
	rShow.getPageAngle = function(a) {
		if (Array.isArray(a))
			return Math.min.apply(null, a);
		return a;
	}
	//获取页面逆向旋转旋转角 参数：角度
	rShow.getrPageAngle = function(a) {
		if (Array.isArray(a))
			return Math.max.apply(null, a);
		return a;
	}
	//绘制页面 参数：页码，初始角度，页码标记
	rShow.drawImg = function(pagenum, a, p) {
		var consult, //参考角
		pimg = pagenum, //标记图片分区
		imgnum = 0//标记当前已展示图片个数
		while (pimg--) {
			imgnum += pages[pimg].modules
		}
		for (var i = 0; i < pages[pagenum].modules; i++) {
			var n = i + imgnum;
			switch(p) {
				case 1:
					pages[pagenum].modules != 1 ? consult = pieces[n].a - r.getrPageAngle(pages[pagenum].angle) : consult = 0;
					break;
				case 0:
					pages[pagenum].modules != 1 ? consult = pieces[n].a : consult = pages[pagenum].angle;
					break;
				case -1:
					pages[pagenum].modules != 1 ? consult = pieces[n].a + r.getrPageAngle(pages[pagenum].angle) : consult = -180;
					break;
				default:
					rShow.rError("Wrong parameter!");
			}
			myCanvasTx.drawImage(pieces[n].image, cX - pieces[n].r * Math.sin((consult - a) * rad), cY - pieces[n].r * Math.cos((consult - a) * rad), pieces[n].width, pieces[n].height);
		}
	}
	//判断浏览器是否支持canvas
	rShow.support = (function() {
		if (!document.createElement('canvas').getContext)
			rShow.rError("Your browser does not support the canvas!");
	})();
	//添加r对象
	window.r = rShow;
})(window)